/* 
 * shamefully copy from AnFetion.
 * more see: http://code.google.com/p/anfetion/
 */
package person.bangbang.im.Androidgin.Fetion;

import java.util.ArrayList;

import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


public class GetFriendsList extends SIPCBase {

    private FetionUri fetionid;
    private int contactsVersion;

    public void setContactsVersion(int contactsVersion) {
        this.contactsVersion = contactsVersion;
    }

    public int getContactsVersion() {
        return contactsVersion;
    }

    private ArrayList<FetionFriend> buddies;

    public ArrayList<FetionFriend> getBuddies() {
        return buddies;
    }

    public GetFriendsList(FetionUri fetionid, TcpSendAndReceive connection, SerialManager serialManager) {
        super(serialManager, connection);
        this.fetionid = fetionid;
    }

    @Override
    public boolean execute() {
        onStatusChanged(StatusDefine.LOGINED, StatusDefine.GETTINGFRIENDS);
        ArrayList<FetionSIPC.HeaderPair> headers = new ArrayList<FetionSIPC.HeaderPair>();

        headers.add(new FetionSIPC.HeaderPair("F", fetionid.getId()));
        headers.add(new FetionSIPC.HeaderPair("I", serialManager.getISerial() + " "));
        headers.add(new FetionSIPC.HeaderPair("Q", String.valueOf(serialManager.getISerial()) + " S"));
        headers.add(new FetionSIPC.HeaderPair("N", "GetContactList"));
        String body = "<args><contacts version=\"0\"><buddy-lists /><buddies attributes=\"all\" />"
                + "<mobile-buddies attributes=\"all\" /><chat-friends /><blacklist /></contacts></args>";
        headers.add(new FetionSIPC.HeaderPair("L", StrUtil.getLength(body)));

        FetionSIPC sipc = new FetionSIPC(SIPC_COMMON_HEADER, headers, body);

        if (this.SendAndReceiveResponse(sipc)) {
            try {
                if (sipc.response.getResponseCmdLine().code.equals(SIPC_RESPONSE_CODE_OK)) {
                    Document dom = parseXmlDocument(sipc.response.body);
                    Element results = dom.getDocumentElement();
                    if (results == null) {
                        this.onSetText("Get friends lists fail");
                        this.onStatusChanged(StatusDefine.GETTINGFRIENDS, StatusDefine.LOGINED);
                        return false;
                    }
                    Node contacts = results.getFirstChild();
                    setContactsVersion(Integer.parseInt(contacts.getAttributes().getNamedItem("version")
                            .getNodeValue()));
                    NodeList buddiesnodes = ((Element) contacts).getElementsByTagName("buddies");
                    buddies = new ArrayList<FetionFriend>();
                    for (int i = 0; i < buddiesnodes.getLength(); i++) {
                        NodeList buddyNodes = buddiesnodes.item(i).getChildNodes();
                        for (int j = 0; j < buddyNodes.getLength(); j++) {
                            Element e = (Element)buddyNodes.item(j);
                            if (e.getNodeName().equals("buddy")) {
                                FetionFriend friend = new FetionFriend();
                                friend.Uri = e.getAttribute("uri");
                                friend.IsMobileNo = false;
                                friend.setFriendName(e.getAttribute("local-name"));
                                friend.type = StrUtil.parseInt(e.getAttribute("relation-status"), 0);
                                friend.onlineNotify = StrUtil.parseInt(e.getAttribute("online-notify"), 0);
                                friend.group = StrUtil.parseInt(e.getAttribute("buddy-lists"), 0);

                                buddies.add(friend);
                            }
                        }
                    }
                    NodeList mobile_buddiesnodes = ((Element) contacts)
                            .getElementsByTagName("mobile-buddies");

                    for (int i = 0; i < mobile_buddiesnodes.getLength(); i++) {
                        NodeList mobile_buddyNodes = mobile_buddiesnodes.item(i).getChildNodes();
                        for (int j = 0; j < mobile_buddyNodes.getLength(); j++) {
                            Element e = (Element)mobile_buddyNodes.item(j);
                            if (e.getNodeName().equals("mobile-buddy")) {
                                FetionFriend friend = new FetionFriend();
                                friend.Uri = e.getAttribute("uri");

                                friend.IsMobileNo = true;
                                friend.mobile_no = (new FetionUri(friend.Uri)).getId();
                                friend.type = StrUtil.parseInt(e.getAttribute("relation-status"), 0);
                                friend.onlineNotify = StrUtil.parseInt(e.getAttribute("online-notify"), 0);
                                friend.setFriendName(e.getAttribute("local-name"));
                                friend.group = StrUtil.parseInt(e.getAttribute("buddy-lists"), 0);
                                buddies.add(friend);
                            }
                        }
                    }
                    this.onSetText("Get friends lists OK");
                    this.onStatusChanged(StatusDefine.GETTINGFRIENDS, StatusDefine.GOTFRIENDS);
                    return true;
                } else {
                    this.onSetText("Get friends lists fail");
                    this.onStatusChanged(StatusDefine.GETTINGFRIENDS, StatusDefine.LOGINED);
                    return false;
                }
            } catch (NumberFormatException e) {
                this.onSetText(e.getMessage());
                e.printStackTrace();
            } catch (DOMException e) {
                this.onSetText(e.getMessage());
                e.printStackTrace();
            } catch (Exception e) {
                this.onSetText(e.getMessage());
                e.printStackTrace();
            }
            this.onStatusChanged(StatusDefine.GETTINGFRIENDS, StatusDefine.LOGINED);
            return false;
        } else {
            this.onSetText("Time out while getting friends lists.");
            this.onStatusChanged(StatusDefine.GETTINGFRIENDS, StatusDefine.LOGINED);
            return false;
        }
    }

}
